home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / usb-creator / install.py next >
Encoding:
Python Source  |  2009-04-17  |  6.0 KB  |  163 lines

  1. #!/usr/bin/python
  2.  
  3. # Copyright (C) 2008 Canonical Ltd.
  4.  
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License version 3,
  7. # as published by the Free Software Foundation.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16.  
  17. import getopt
  18. import os
  19. import stat
  20. import sys
  21. import shutil
  22. import subprocess
  23.  
  24. def popen(cmd):
  25.     print >>sys.stderr, str(cmd)
  26.     process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
  27.         stderr=sys.stderr, stdin=subprocess.PIPE)
  28.     process.communicate()
  29.     return process
  30.  
  31. def main(source, target, persist):
  32.     # Some of the code in this function was copied from Ubiquity's
  33.     # scripts/install.py
  34.  
  35.     sys.stdout.write('Copying files\n')
  36.     sys.stdout.flush()
  37.     if not os.path.exists(source) or not os.path.exists(target):
  38.         print >>sys.stderr, 'Source or target does not exist.'
  39.         sys.exit(1)
  40.     for dirpath, dirnames, filenames in os.walk(source):
  41.         sp = dirpath[len(source) + 1:]
  42.         for name in dirnames + filenames:
  43.             relpath = os.path.join(sp, name)
  44.             sourcepath = os.path.join(source, relpath)
  45.             targetpath = os.path.join(target, relpath)
  46.             st = os.lstat(sourcepath)
  47.             mode = stat.S_IMODE(st.st_mode)
  48.             if stat.S_ISLNK(st.st_mode):
  49.                 if os.path.lexists(targetpath):
  50.                     os.unlink(targetpath)
  51.                 linkto = os.readlink(sourcepath)
  52.                 #os.symlink(linkto, targetpath)
  53.                 # FIXME: Handle this somehow?
  54.                 sys.stderr.write('Tried to symlink %s -> %s\n' % \
  55.                     (linkto, targetpath))
  56.                 pass
  57.             elif stat.S_ISDIR(st.st_mode):
  58.                 if not os.path.isdir(targetpath):
  59.                     os.mkdir(targetpath, mode)
  60.             elif stat.S_ISCHR(st.st_mode):
  61.                 os.mknod(targetpath, stat.S_IFCHR | mode, st.st_rdev)
  62.             elif stat.S_ISBLK(st.st_mode):
  63.                 os.mknod(targetpath, stat.S_IFBLK | mode, st.st_rdev)
  64.             elif stat.S_ISFIFO(st.st_mode):
  65.                 os.mknod(targetpath, stat.S_IFIFO | mode)
  66.             elif stat.S_ISSOCK(st.st_mode):
  67.                 os.mknod(targetpath, stat.S_IFSOCK | mode)
  68.             elif stat.S_ISREG(st.st_mode):
  69.                 if os.path.exists(targetpath):
  70.                     os.unlink(targetpath)
  71.                 fail = False
  72.                 try:
  73.                     sourcefh = open(sourcepath, 'rb')
  74.                     targetfh = open(targetpath, 'wb')
  75.                     # TODO: md5 check.
  76.                     try:
  77.                         shutil.copyfileobj(sourcefh, targetfh)
  78.                     except Exception, e:
  79.                         fail = True
  80.                         print >>sys.stderr, str(e) + '\n'
  81.                 finally:
  82.                     sourcefh.close()
  83.                     targetfh.close()
  84.                     if fail:
  85.                         sys.exit(1)
  86.     
  87.     # Modify contents to be suitable for a USB drive.
  88.     popen(['rm', '-rf', '%s/syslinux' % target])
  89.     popen(['mv', '%s/isolinux' % target, '%s/syslinux' % target])
  90.     popen(['mv', '%s/syslinux/isolinux.cfg' % target,
  91.             '%s/syslinux/syslinux.cfg' % target])
  92.     for filename in ['syslinux/syslinux.cfg', 'syslinux/text.cfg']:
  93.         f = None
  94.         try:
  95.             f = open(os.path.join(target, filename), 'r')
  96.             label = ''
  97.             to_write = []
  98.             for line in f.readlines():
  99.                 line = line.strip('\n').split(' ')
  100.                 for l in line:
  101.                     if l:
  102.                         command = l
  103.                         break
  104.                 if command.lower() == 'append':
  105.                     pos = line.index(command) + 2
  106.                     if label not in ('check', 'memtest', 'hd'):
  107.                         if persist != '0':
  108.                             line.insert(pos, 'persistent')
  109.                         line.insert(pos, 'cdrom-detect/try-usb=true')
  110.                     if label not in ('memtest', 'hd'):
  111.                         line.insert(pos, 'noprompt')
  112.                 elif command.lower() == 'label':
  113.                     label = line[1].strip()
  114.                 to_write.append(' '.join(line) + '\n')
  115.             f.close()
  116.             f = open(os.path.join(target, filename), 'w')
  117.             f.writelines(to_write)
  118.         except Exception, e:
  119.             print >>sys.stderr, str(e) + '\n'
  120.             print >>sys.stderr, 'Unable to add persistence to the ' \
  121.                 'configuration (%s)\n' % filename
  122.         finally:
  123.             if f:
  124.                 f.close()
  125.     
  126.     # /syslinux.cfg is present to work around a bug.
  127.     # TODO: find bug number.  Wasn't this fixed in Intrepid?
  128.     popen(['cp', '%s/syslinux/syslinux.cfg' % target,
  129.         '%s/syslinux.cfg' % target])
  130.     
  131.     if persist != '0':
  132.         sys.stdout.write('Creating persistence file\n')
  133.         sys.stdout.flush()
  134.         popen(['dd', 'if=/dev/zero', 'bs=%s' % persist, 'of=%s/casper-rw' % target, 'count=1'])
  135.         sys.stdout.write('Making persistence filesystem\n')
  136.         sys.stdout.flush()
  137.         popen(['mkfs.ext3', '-F', '%s/casper-rw' % target])
  138.     popen(['sync'])
  139.  
  140. if __name__ == '__main__':
  141.     source = ''
  142.     target = ''
  143.     persist = 0
  144.     try:
  145.         opts, args = getopt.getopt(sys.argv[1:], 's:t:p:')
  146.     except getopt.GetoptError:
  147.         sys.exit(1)
  148.     for opt, arg in opts:
  149.         if opt == '-s':
  150.             source = arg
  151.         elif opt == '-t':
  152.             target = arg
  153.         elif opt == '-p':
  154.             persist = arg
  155.     if source and target:
  156.         main(source, target, persist)
  157.         sys.exit(0)
  158.     else:
  159.         print >> sys.stderr, \
  160.             'Source or target device not specified.  Cannot continue.\n'
  161.         sys.exit(1)
  162.  
  163.